
#include <QScrollBar>
#include <QScrollArea>

#include "procycle.h"
#include "ganttscene.h"
#include "ganttgrads.h"
#include "ganttview.h"
#include "timeaxis.h"
#include "tasktreeview.h"
#include "viewmanager.h"


ViewManager::ViewManager(ProCycle *app,
                         GanttView *gv,
                         GanttScene *gs,
                         GanttRuler *ruler,
                         QScrollArea *rsa,
                         TaskTreeView *ttv,
                         QScrollBar *vsb) :
    PCChild(app), m_policyDone(false), m_gv(gv), m_gs(gs), m_ruler(ruler), m_rsa(rsa), m_ttv(ttv), m_vsb(vsb)
{
    m_ttv->setVerticalScrollMode(QTreeView::ScrollPerPixel);
    m_ttv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_gv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_gv->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_rsa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_rsa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);


    QObject::connect(m_ttv->verticalScrollBar(), SIGNAL(valueChanged(int)),
                     this, SLOT(scrollVertical(int)));
    QObject::connect(m_gv->verticalScrollBar(), SIGNAL(valueChanged(int)),
                     this, SLOT(scrollVertical(int)));
    QObject::connect(m_vsb, SIGNAL(valueChanged(int)),
                     this, SLOT(scrollVertical(int)));
    QObject::connect(m_ttv->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
                     this, SLOT(rangeVertical(int,int)));
    QObject::connect(m_gv->verticalScrollBar(), SIGNAL(rangeChanged(int,int)),
                     this, SLOT(rangeVertical(int,int)));

    QObject::connect(m_rsa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
                     this, SLOT(scrollHorizontal(int)));
    QObject::connect(m_gv->horizontalScrollBar(), SIGNAL(valueChanged(int)),
                     this, SLOT(scrollHorizontal(int)));
    QObject::connect(m_rsa->horizontalScrollBar(), SIGNAL(rangeChanged(int,int)),
                     this, SLOT(rangeHorizontal(int,int)));
    QObject::connect(m_gv->horizontalScrollBar(), SIGNAL(rangeChanged(int,int)),
                     this, SLOT(rangeHorizontal(int,int)));

    QObject::connect(m_gv, SIGNAL(resized(QSize)), this, SLOT(processGanttViewResize(QSize)));
}


TimeAxis *ViewManager::axis() const {
    return app()->axis();
}


void ViewManager::initSizePolicy() {
    m_policyDone = true;
    m_minSize = m_gv->size();
    m_gs->setSceneRect(0, 0, m_minSize.width(), m_minSize.height());
    m_ruler->resize(QSize(m_minSize.width(), app()->headerHeight()));
    axis()->setLength(61);
    rangeVertical(m_gv->verticalScrollBar()->minimum(), m_gv->verticalScrollBar()->maximum());
}



void ViewManager::processGanttViewResize(QSize newSize) {
    if (m_policyDone) {
        m_minSize = m_gv->size();
        QSize ss = m_gs->preferredSize();
        if (ss.width() < m_minSize.width()) {
            ss.setWidth(m_minSize.width());
        }
        if (ss.height() < m_minSize.height()) {
            ss.setHeight(m_minSize.height());
        }
        m_gs->setSceneRect(0, 0, ss.width(), ss.height());
        m_ruler->resize(QSize(ss.width(), app()->headerHeight()));
    }
}


void ViewManager::resizeScene(QSize newSize) {
    m_minSize = m_gv->size();
    if (newSize.width() < m_minSize.width()) {
        newSize.setWidth(m_minSize.width());
    }
    if (newSize.height() < m_minSize.height()) {
        newSize.setHeight(m_minSize.height());
    }
    m_gs->setSceneRect(0, 0, newSize.width(), newSize.height());
    m_ruler->resize(QSize(newSize.width(), app()->headerHeight()));
}


inline void sbSetRange(QScrollBar *sb, int min, int max) {
    if (sb->minimum() != min || sb->maximum() != max) {
        sb->setRange(min, max);
    }
}

inline void sbSetValue(QScrollBar *sb, int val) {
    if (sb->value() != val) {
        sb->setValue(val);
    }
}



void ViewManager::scrollVertical(int scroll) {
    sbSetValue(m_gv->verticalScrollBar(), scroll);
    sbSetValue(m_ttv->verticalScrollBar(), scroll);
    sbSetValue(m_vsb, scroll);
}


void ViewManager::scrollHorizontal(int scroll) {
    sbSetValue(m_gv->horizontalScrollBar(), scroll);
    sbSetValue(m_rsa->horizontalScrollBar(), scroll);
}

void ViewManager::rangeVertical(int min, int max) {
    sbSetRange(m_gv->verticalScrollBar(), min, max);
    sbSetRange(m_ttv->verticalScrollBar(), min, max);
    sbSetRange(m_vsb, min, max);
}

void ViewManager::rangeHorizontal(int min, int max) {
    sbSetRange(m_gv->horizontalScrollBar(), min, max);
    sbSetRange(m_rsa->horizontalScrollBar(), min, max);
}

